home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
dev
/
lang
/
fpc09905c.lha
/
fpc
/
inc
/
real2str.inc
< prev
next >
Wrap
Text File
|
1998-09-21
|
6KB
|
234 lines
{
$Id: real2str.inc,v 1.10 1998/08/11 21:39:06 peter Exp $
This file is part of the Free Pascal run time library.
Copyright (c) 1997 by Michael Van Canneyt,
member of the Free Pascal development team
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
type
treal_type = (rt_s64real,rt_s32real,rt_f32bit,rt_s80real,rt_s64bit);
{ corresponding to real single fixed extended and comp for i386 }
{$ifdef i386}
{$ifdef DEFAULT_EXTENDED}
bestreal = extended;
{$else}
bestreal = double;
{$endif DEFAULT_EXTENDED}
{$else i386}
bestreal = single;
{$endif i386}
Procedure str_real (len,f : longint; d : bestreal; real_type :treal_type; var s : string);
{
These numbers are for the double type...
At the moment these are mapped onto a double but this may change
in the future !
}
var maxlen : longint; { Maximal length of string for float }
minlen : longint; { Minimal length of string for float }
explen : longint; { Length of exponent, including E and sign.
Must be strictly larger than 2 }
const
maxexp = 1e+35; { Maximum value for decimal expressions }
minexp = 1e-35; { Minimum value for decimal expressions }
zero = '0000000000000000000000000000000000000000';
var correct : longint; { Power correction }
currprec : longint;
roundcorr : bestreal;
temp : string;
power : string[10];
sign : boolean;
i : integer;
dot : byte;
begin
case real_type of
rt_s64real :
begin
maxlen:=23;
minlen:=9;
explen:=5;
end;
rt_s32real :
begin
maxlen:=16;
minlen:=8;
explen:=4;
end;
rt_f32bit :
begin
maxlen:=16;
minlen:=8;
explen:=4;
end;
rt_s80real :
begin
maxlen:=26;
minlen:=10;
explen:=6;
end;
rt_s64bit :
begin
maxlen:=22;
minlen:=9;
{ according to TP (was 5) (FK) }
explen:=6;
end;
end;
{ check parameters }
{ default value for length is -32767 }
if len=-32767 then len:=maxlen;
{ determine sign. before precision, needs 2 less calls to abs() }
sign:=d<0;
{ the creates a cannot determine which overloaded function to call
if d is extended !!!
we should prefer real_to_real on real_to_longint !!
corrected in compiler }
{ d:=abs(d); this converts d to double so we loose precision }
{ for the same reason I converted d:=frac(d) to d:=d-int(d); (PM) }
if sign then d:=-d;
{ determine precision : maximal precision is : }
currprec:=maxlen-explen-3;
{ this is also the maximal number of decimals !!}
if f>currprec then f:=currprec;
{ when doing a fixed-point, we need less characters.}
if (f<0) or ( (d<>0) and ((d>maxexp) or (d<minexp))) then
begin
{ determine maximal number of decimals }
if (len>=0) and (len<minlen) then len:=minlen;
if (len>0) and (len<maxlen) then
currprec:=len-explen-3;
end;
{ convert to standard form. }
correct:=0;
if d>=10.0 then
while d>=10.0 do
begin
d:=d/10.0;
inc(correct);
end
else if (d<1) and (d<>0) then
while d<1 do
begin
d:=d*10.0;
dec(correct);
end;
{ RoundOff }
roundcorr:=0.5;
if f<0 then
for i:=1 to currprec do roundcorr:=roundcorr/10
else
for i:=1 to correct+f do roundcorr:=roundcorr/10;
d:=d+roundcorr;
{ 0.99 + 0.05 > 10.0 ! Fix this by dividing the results >=10 first (PV) }
if d>=10.0 then
begin
d:=d/10.0;
inc(correct);
end;
{ Now we have a standard expression : sign d *10^correct
where 1<d<10 or d=0 ... }
{ get first character }
if sign then
temp:='-'
else
temp:=' ';
temp:=temp+chr(ord('0')+trunc(d));
d:=d-int(d);
{ Start making the string }
for i:=1 to currprec do
begin
d:=d*10.0;
temp:=temp+chr(ord('0')+trunc(d));
d:=d-int(d);
end;
{ Now we need two different schemes for the different
representations. }
if (f<0) or (correct>maxexp) then
begin
insert ('.',temp,3);
str(abs(correct),power);
if length(power)<explen-2 then
power:=copy(zero,1,explen-2-length(power))+power;
if correct<0 then power:='-'+power else power:='+'+power;
temp:=temp+'E'+power;
end
else
begin
if not sign then
begin
delete (temp,1,1);
dot:=2;
end
else
dot:=3;
{ set zeroes and dot }
if correct>=0 then
begin
if length(temp)<correct+dot+f then
temp:=temp+copy(zero,1,correct+dot+f-length(temp));
insert ('.',temp,correct+dot);
end
else
begin
correct:=abs(correct);
insert(copy(zero,1,correct),temp,dot-1);
insert ('.',temp,dot);
end;
{correct length to fit precision.}
if f>0 then
temp[0]:=chr(pos('.',temp)+f)
else
temp[0]:=chr(pos('.',temp)-1);
end;
if length(temp)<len then
s:=space(len-length(temp))+temp
else
s:=temp;
end;
{
$Log: real2str.inc,v $
Revision 1.10 1998/08/11 21:39:06 peter
* splitted default_extended from support_extended
Revision 1.9 1998/08/11 00:05:25 peter
* $ifdef ver0_99_5 updates
Revision 1.8 1998/08/10 15:56:30 peter
* fixed 0_9_5 typo
Revision 1.7 1998/08/08 12:28:12 florian
* a lot small fixes to the extended data type work
Revision 1.6 1998/07/18 17:14:22 florian
* strlenint type implemented
Revision 1.5 1998/07/13 21:19:10 florian
* some problems with ansi string support fixed
Revision 1.4 1998/06/18 08:15:33 michael
+ Fixed error when printing zero. len was calculated wron.
Revision 1.3 1998/05/12 10:42:45 peter
* moved getopts to inc/, all supported OS's need argc,argv exported
+ strpas, strlen are now exported in the systemunit
* removed logs
* removed $ifdef ver_above
Revision 1.2 1998/04/07 22:40:46 florian
* final fix of comp writing
}